<?php
include_once "mdbtable.php";

class MUser extends MDbTable {

	public $table = "user";

	private $_users = array();
	private $_root = array();



	protected function _createSqlByFilters($filters)
	{
		$this->db->select('t.*');
		foreach($filters as $filter_key => $filter_value)
		{
			switch($filter_key)
			{
				case 'email':
					if(is_array($filter_value))
					{
						if(count($filter_value))
						{
							$this->db->where_in('trim(email)', $filter_value);
						}
					}
					else
					{
						$this->db->where('trim(email)', $filter_value);
					}
					unset($filters[$filter_key]);
					break;

				case 'email_search':
					$this->db->like('email', $filter_value);
					unset($filters[$filter_key]);
					break;

				case 'fio_search':
					$this->db->like('fio', $filter_value);
					unset($filters[$filter_key]);
					break;
				
				case 'hi_like':
					$this->db->like('hi', $filter_value, 'after');
					unset($filters[$filter_key]);
					break;
				
				case 'has_oper':
					$CI = &get_instance();
					$this->db->where('(SELECT count(*) FROM '.$this->db->dbprefix.$CI->MOper->table.' where user_id = t.id) > 0', null, false);
					unset($filters[$filter_key]);
					break;
				
				case 'add_fields':
					foreach($filter_value as $f)
					{
						switch($f)
						{
							case "referer_fio":
								$this->db->select('(SELECT fio FROM '.$this->db->dbprefix.$this->table.' WHERE email = t.referer_email) referer_fio', false);
								break;

							case "hi_level":
								$this->db->select('hi_level(hi) hi_level', false);
								break;
							
						}
					}
					break;
			}
		}
		return parent::_createSqlByFilters($filters);
	}
	
	protected function _modifyRow(&$row)
	{
		global $USER_LEVEL;
		if($row['level'] && isset($USER_LEVEL[$row['level']]))
		{
			$row['status'] = $USER_LEVEL[$row['level']]." (30%)";
		}
		else
		{
			$row['status'] = $row['lgota'] ? $row['lgota']." (30%)" : 'Участник (20%)';
		}
		list($year, $month, $day) = explode("-", $row['date']);
		$row['day'] = $day;
		$row['month'] = $month;
		$row['year'] = $year;
		parent::_modifyRow($row);
	}

	public function getList($filters = array())
	{
		if(!isset($filters['sort']))
		{
			$filters['sort'] = 'fio asc';
		}
		if(!isset($filters['add_fields']))
		{
			$filters['add_fields'] = array();
		}
		if(!in_array('referer_fio', $filters['add_fields']))
		{
			$filters['add_fields'][] = 'referer_fio';
		}
		$rows = parent::getList($filters);
		$desyatnik = isset($rows[1]) ? $rows[1] : null;
		$users = array();
		foreach($rows as $row)
		{
			$users[$row['id']] = $row;
		}
		return $users;
	}

	public function get($id, $no_cash = false)
	{
		$id = intval($id);
		if(@$this->_users[$id] && !$no_cash)
		{
			return $this->_users[$id];
		}
		else
		{
			$row = parent::get($id);
			$this->_users[$id] = &$row;
			return $row;
		}
	}

	public function getChildrenAndMe($parent_id)
	{
		$users = array_merge(
			array($parent_id => $this->get($parent_id)),
			$this->getList(array('parent_id' => $parent_id, 'sort' => 'level desc,fio asc')));
		$users_index = array();
		foreach($users as $user)
		{
			$users_index[$user['id']] = $user;
		}
		return $users_index;
	}

	public function getMyStructure($parent_id)
	{
		$filters = array('parent_id' => $parent_id, 'level>=' => '*', 'sort' => 'level desc,fio asc');
		$children = $this->getList($filters);
		foreach($children as $k => $user)
		{
			if($user['level'] >= '*')
			{
				$ch = $this->getMyStructure($user['id']);
				if(count($ch))
				{
					$children[$k]['children'] = $ch;
				}
			}
		}

		return $children;
	}

	public function getReferers($glava)
	{
		$this->db->select('referer_email');
		$this->db->like('hi', $glava['hi']."%", 'after');
		$this->db->where('referer_email NOT IN ((SELECT email FROM '.$this->db->dbprefix.$this->table.' WHERE hi LIKE "'.$glava['hi'].'%"))', null, false);
		$res = $this->db->get($this->table);
		$emails = array();
		foreach ($res->result_array() as $row)
		{
			if($row['referer_email']) $emails[trim($row['referer_email'])] = trim($row['referer_email']);
		}
		$rows = count($emails) ? $this->getList(array('email' => $emails)) : array();
		$out = array();
		foreach($rows as $row)
		{
			$out[$row['email']] = $row;
		}
		return $out;
	}

	public function getRoot()
	{
		if(!@$this->_root['id'])
		{
			$me = $this->get(Auth::$user_id);
			$root_hi = getParentHi($me['hi'], 1);
			$this->_root = $this->getFirstRow(array('hi' => $root_hi));
		}
		return $this->_root;
	}

	public function getDateUpLevel($user_id)
	{
		static $dates = array();
		if(!isset($dates[$user_id]))
		{
			$dates[$user_id] = null;
			$this->db->order_by('date', 'asc');
			$this->db->where('user_id',  $user_id);
			$this->db->limit(1);
			$this->db->from('change_level');
			$row = $this->db->get('change_level')->first_row('array');
			if(!empty($row))
			{
				$dates[$user_id] = $row['date'];
			}
		}
		return $dates[$user_id];
	}

	public function getRowsChangeLevel($user_id)
	{
		$this->db->order_by('date', 'asc');
		$this->db->where('user_id',  $user_id);
		return $this->db->get('change_level')->result_array();
	}

	public function isLgota($user, $date, $oper_type = null)
	{
		$out = trim($user['lgota']) != '';
		if(!$out)
		{
			if($user['level'] != '')
			{
				global $TYPE_OPER_SELL;
				$date = dateToDb($date);
				$date_ch_level = $this->getDateUpLevel($user['id']);
				if($date_ch_level && ($date_ch_level < $date || ($date_ch_level == $date && !in_array($oper_type, $TYPE_OPER_SELL))))
				{
					$out = true;
				}
			}
		}
		return $out;
	}

	public function saveChLevel($arr)
	{
		$where = array('user_id' => $arr['user_id'], 'level' => $arr['level']);
		if($this->db->get_where('change_level', $where)->num_rows()) 
		{
			$update = array('date' => $arr['date']);
			$this->db->update('change_level', $update, $where);
		}
		else
		{
			$this->db->insert('change_level', $arr);
		}
	}

	public function insert($arr, &$id)
	{
		$arr['time_add'] = time();
		parent::insert($arr, $id);
		$parent = $this->get(@$arr['parent_id']);
		$parent_hi = @$parent['hi'];
		$this->db->query('
			UPDATE 
				'.$this->db->dbprefix.$this->table.' 
			SET 
				hi = get_next_hi(get_last_user_hi("'.$parent_hi.'")) 
			WHERE
				id = '.$id.'
		');
	}

	public function getDesyatnikId($user_id, $date)
	{
		$CI = &get_instance();
		$date = dateToDb($date);
		$user = $this->get($user_id);
		$parent_id = @$user['parent_id'];
		$moves = $CI->MChangeParentUser->getList(array('user_id' => $user_id, 'sort' => 'date desc'));
		foreach($moves as $move)
		{
			if($move['date'] <= $date)
			{
				$parent_id = $move['new_parent_id'];
				break;
			}
			else
			{
				$parent_id = $move['last_parent_id'];
			}
		}
		return $parent_id;
	}

	public function isMyChild($user_id)
	{
		$user_id = intval($user_id);
		$out = $user_id > 0 && $user_id == Auth::$user_id;
		if(!$out)
		{
			$this->db->from($this->table);
			$this->db->where(array('id' => $user_id, 'parent_id' => Auth::$user_id));
			$out = $this->db->count_all_results() > 0;
		}
		return $out;
	}

	public function inMyStructure($user_id)
	{
		$out = false;
		$user_id = intval($user_id);
		if($user_id > 0)
		{
			$out = $user_id == Auth::$user_id;
			if(!$out)
			{
				$user = $this->get($user_id);
				$out = $out || $this->inMyStructure($user['parent_id']);
			}
		}
		return $out;
	}

	public function isCanOper($user_id, $check_child = true)
	{
		static $root_id;
		if(!$root_id)
		{
			$root = $this->getRoot();
			$root_id = $root['id'];
		}
		$out = $user_id > 0 && (Auth::isSupport() || Auth::$user_id == $root_id);
		if(!$out && $check_child)
		{
			$out = $this->isMyChild($user_id);
		}
		return $out;
	}

	public function delete($id)
	{
		$this->db->delete('change_level', array('user_id' => $id));
		$this->db->or_where('user_id', $id);
		$this->db->or_where('last_parent_id', $id);
		$this->db->or_where('new_parent_id', $id);
		$this->db->delete('change_parent_user');
		parent::delete($id);
	}

	public function updateNewHi($old_parent_user)
	{
		$new_parent_user = $this->get($old_parent_user['id'], true);
		$parent = $this->get($new_parent_user['parent_id'], true);
		$parent_hi = @$parent['hi'];
		$this->db->query('
			UPDATE 
				'.$this->db->dbprefix.$this->table.' 
			SET 
				hi = get_next_hi(get_last_user_hi("'.$parent_hi.'")) 
			WHERE
				id = '.$old_parent_user['id'].'
		');

		$new_parent_user = $this->get($old_parent_user['id'], true);
		$this->db->query('
			UPDATE 
				'.$this->db->dbprefix.$this->table.' 
			SET 
				hi = concat("'.$new_parent_user['hi'].'", substring(hi, '.(strlen($old_parent_user['hi']) + 1).')) 
			WHERE
				hi like "'.$old_parent_user['hi'].'.%"
		');
	}

}

